import { Request, Response, NextFunction } from 'express';
import ApiResponse from '@/utils/api/api-response.util';
import { isEmpty, isValidEmail, isValidPhone, isValidPassword, isValidStatus } from '../common/validation.util';
import userService from '@/services/system/user.service';
import { getLogger } from '@/utils/logger';
import { AuthRequest } from '@/types';

const logger = getLogger('user-validator', { console: false });
const consoleLogger = getLogger('user-validator');

/**
 * 验证用户创建参数
 */
export const validateUserCreate = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { userName, phonenumber, email } = req.body;
    
    // 用户名验证
    if (isEmpty(userName)) {
      return ApiResponse.error(res, '用户名不能为空', 400);
    }
    
    // 校验用户名是否唯一
    if (!(await userService.checkUserNameUnique(userName))) {
      consoleLogger.warn('新增用户失败: 登录账号已存在', { userName });
      return ApiResponse.error(res, '新增用户失败，登录账号已存在', 400);
    }
    
    // 手机号验证
    if (!isEmpty(phonenumber)) {
      if (!isValidPhone(phonenumber)) {
        return ApiResponse.error(res, '手机号格式不正确', 400);
      }
      // 校验手机号是否唯一
      if (!(await userService.checkPhoneUnique(phonenumber))) {
        consoleLogger.warn('新增用户失败: 手机号码已存在', { phonenumber });
        return ApiResponse.error(res, '新增用户失败，手机号码已存在', 400);
      }
    }
    
    // 邮箱验证
    if (!isEmpty(email)) {
      if (!isValidEmail(email)) {
        return ApiResponse.error(res, '邮箱格式不正确', 400);
      }
      // 校验邮箱是否唯一
      if (!(await userService.checkEmailUnique(email))) {
        consoleLogger.warn('新增用户失败: 邮箱账号已存在', { email });
        return ApiResponse.error(res, '新增用户失败，邮箱账号已存在', 400);
      }
    }
    
    logger.debug('用户创建参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`用户创建验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证用户更新参数
 */
export const validateUserUpdate = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const userId = parseInt(req.body.userId);
    const { userName, phonenumber, email } = req.body;
    
    if (isNaN(userId) || userId <= 0) {
      return ApiResponse.error(res, '用户ID无效', 400);
    }
    
    // 校验用户是否存在
    const user = await userService.getUserById(userId);
    if (!user) {
      logger.warn('修改用户失败: 用户不存在', { userId });
      return ApiResponse.error(res, '修改用户失败，用户不存在', 400);
    }
    
    // 校验用户名是否唯一
    if (userName !== user.data.userName && !(await userService.checkUserNameUnique(userName, userId))) {
      logger.warn('修改用户失败: 登录账号已存在', { userName });
      return ApiResponse.error(res, '修改用户失败，登录账号已存在', 400);
    }
    
    // 校验手机号是否唯一
    if (phonenumber && phonenumber !== user.data.phonenumber && !(await userService.checkPhoneUnique(phonenumber, userId))) {
      logger.warn('修改用户失败: 手机号码已存在', { phonenumber });
      return ApiResponse.error(res, '修改用户失败，手机号码已存在', 400);
    }
    
    // 校验邮箱是否唯一
    if (email && email !== user.data.email && !(await userService.checkEmailUnique(email, userId))) {
      logger.warn('修改用户失败: 邮箱账号已存在', { email });
      return ApiResponse.error(res, '修改用户失败，邮箱账号已存在', 400);
    }
    
    logger.debug('用户更新参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`用户更新验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证重置密码参数
 */
export const validateResetPwd = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { userId, password } = req.body;
    
    if (isEmpty(userId) || isNaN(parseInt(userId))) {
      return ApiResponse.error(res, '用户ID不能为空', 400);
    }
    
    if (isEmpty(password)) {
      return ApiResponse.error(res, '密码不能为空', 400);
    }
    
    if (!isValidPassword(password)) {
      return ApiResponse.error(res, '密码长度不能少于6位', 400);
    }
    
    logger.debug('重置密码参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`重置密码验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证修改用户状态参数
 */
export const validateChangeStatus = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { userId, status } = req.body;
    
    if (isEmpty(userId) || isNaN(parseInt(userId))) {
      return ApiResponse.error(res, '用户ID不能为空', 400);
    }
    
    if (isEmpty(status)) {
      return ApiResponse.error(res, '状态不能为空', 400);
    }
    
    if (!isValidStatus(status)) {
      return ApiResponse.error(res, '状态值无效', 400);
    }
    
    logger.debug('修改用户状态参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`修改用户状态验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证修改个人信息参数
 */
export const validateUpdateProfile = async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const userId = req.user?.userId;
    const { phonenumber, email } = req.body;
    
    if (!userId) {
      return ApiResponse.error(res, '用户未登录', 401);
    }
    
    // 校验手机号是否唯一
    if (phonenumber && !(await userService.checkPhoneUnique(phonenumber, userId))) {
      return ApiResponse.error(res, '修改个人信息失败，手机号码已存在', 400);
    }
    
    // 校验邮箱是否唯一
    if (email && !(await userService.checkEmailUnique(email, userId))) {
      return ApiResponse.error(res, '修改个人信息失败，邮箱账号已存在', 400);
    }
    
    logger.debug('修改个人信息参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`修改个人信息验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证修改个人密码参数
 */
export const validateUpdatePwd = async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const userId = req.user?.userId;
    const { oldPassword, newPassword } = req.body;
    
    if (!userId) {
      return ApiResponse.error(res, '用户未登录', 401);
    }
    
    if (isEmpty(oldPassword)) {
      return ApiResponse.error(res, '旧密码不能为空', 400);
    }
    
    if (isEmpty(newPassword)) {
      return ApiResponse.error(res, '新密码不能为空', 400);
    }
    
    if (!isValidPassword(newPassword)) {
      return ApiResponse.error(res, '新密码长度不能少于6位', 400);
    }
    
    if (oldPassword === newPassword) {
      return ApiResponse.error(res, '新密码不能与旧密码相同', 400);
    }
    
    // 校验旧密码是否正确
    const user = await userService.getUserByUserName(req.user?.userName || '');
    if (!user || !user.validatePassword(oldPassword)) {
      return ApiResponse.error(res, '修改密码失败，旧密码错误', 400);
    }
    
    logger.debug('修改个人密码参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`修改个人密码验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证用户注册参数
 */
export const validateRegister = async (req: Request, res: Response, next: NextFunction) => {
  try {
    // 1. 注册开关校验
    const sysConfigService = (await import('@/services/system/sys-config.service')).default;
    const registerUser = await sysConfigService.getConfigValueByKey('sys.account.registerUser');
    if (registerUser === 'false') {
      return ApiResponse.error(res, '当前系统未开放注册功能', 403);
    }
    
    const { username, password, confirmPassword, code, uuid } = req.body;
    
    // 2. 参数验证
    if (!username || !password || !confirmPassword) {
      return ApiResponse.error(res, '账号和密码不能为空', 400);
    }
    
    if (password !== confirmPassword) {
      return ApiResponse.error(res, '两次输入的密码不一致', 400);
    }
    
    // 3. 校验验证码（如开启）
    const captchaEnabled = await sysConfigService.getConfigValueByKey('sys.account.captchaEnabled');
    if (captchaEnabled !== 'false') {
      if (!code || !uuid) {
        return ApiResponse.error(res, '验证码不能为空', 400);
      }
      const CaptchaUtil = (await import('@/utils/captcha.util')).default;
      const captchaValid = await CaptchaUtil.validate(uuid, code);
      if (!captchaValid) {
        return ApiResponse.error(res, '验证码错误', 400);
      }
    }
    
    // 4. 校验用户名唯一
    if (!(await userService.checkUserNameUnique(username))) {
      return ApiResponse.error(res, '注册失败，账号已存在', 400);
    }
    
    logger.debug('用户注册参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`用户注册验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证删除用户参数
 */
export const validateRemove = async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const userIds = req.params.userIds.split(',').map(id => parseInt(id));
    
    // 检查是否包含当前登录用户
    if (req.user && userIds.includes(req.user.userId)) {
      return ApiResponse.error(res, '当前用户不能删除', 400);
    }
    
    logger.debug('删除用户参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`删除用户验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证用户头像上传
 */
export const validateAvatarUpload = async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const userId = req.user?.userId;
    
    if (!userId) {
      return ApiResponse.error(res, '用户未登录', 401);
    }
    
    if (!req.file) {
      return ApiResponse.error(res, '上传文件不能为空', 400);
    }
    
    // 检查文件类型
    const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/jpg'];
    if (!allowedTypes.includes(req.file.mimetype)) {
      return ApiResponse.error(res, '只能上传JPG、PNG或GIF格式的图片', 400);
    }
    
    logger.debug('用户头像上传参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`用户头像上传验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
}; 